package com.xingkeduo.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xingkeduo.configuration.formatters.CustomDateFormat;
import com.xingkeduo.configuration.websocket.WebsocketMessageResponse;
import com.xingkeduo.dao.workpad.TStaffAttendanceMapper;
import com.xingkeduo.dao.workpad.TStaffClockInMapper;
import com.xingkeduo.dao.workpad.TStaffStockMapper;
import com.xingkeduo.model.bo.AttendanceTypeEnum;
import com.xingkeduo.model.bo.AttendanceWorkStatusEnum;
import com.xingkeduo.model.bo.StockStatusEnum;
import com.xingkeduo.model.dto.ManagerDTO;
import com.xingkeduo.model.param.AttendancePageParam;
import com.xingkeduo.model.param.AttendanceParam;
import com.xingkeduo.model.po.TStaffAttendance;
import com.xingkeduo.model.po.TStaffClockIn;
import com.xingkeduo.model.po.TStaffStock;
import com.xingkeduo.model.po.TStoreWorkPlan;
import com.xingkeduo.model.vo.*;
import com.xingkeduo.send.RabbitMqSender;
import com.xingkeduo.service.ShopDayService;
import com.xingkeduo.service.StaffAttendanceService;
import com.xingkeduo.service.StorePlanService;
import com.xingkeduo.service.*;
import com.xingkeduo.util.TimeUtil;
import com.xingkeduo.util.tool.CommonUtil;
import com.xingkeduo.util.tool.ResponseMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.xingkeduo.configuration.websocket.WebsocketMessageResponse.MessageTypeEnum.WORKPAD;
import static java.util.Comparator.comparing;

/**
 * 考勤服务实现
 *
 * @Author: 中文输入法发挥不稳定的刘川
 * @Date: 19-3-15 下午7:08
 */
@Service
public class StaffAttendanceServiceImpl implements StaffAttendanceService {

    private static Logger log = LoggerFactory.getLogger(StaffAttendanceServiceImpl.class);

    @Autowired
    TStaffAttendanceMapper staffAttendanceMapper;
    @Autowired
    StorePlanService storePlanService;
    @Autowired
    ShopDayService shopDayService;
    @Autowired
    ShopService shopInfoService;
    @Autowired
    StaffStockService staffStockService;
    //服务间调用
    @Autowired
    OtherService otherService;

    //中间件
    @Autowired
    private RabbitMqSender rabbitMqSender;

    @Autowired
    private TStaffClockInMapper staffClockInMapper;

    @Autowired
    private TStaffStockMapper staffStockMapper;

    @Override
    public int batchInsertForInit(List<TStaffAttendance> attendanceList) {
        int rows = staffAttendanceMapper.batchInsertForInit(attendanceList);
        return rows;
    }

    @Override
    public int initAttendanceForOneStaff(Long staffId, String staffName, Long storeId, String storeName, Long managerId, Date mondayDate) {
        List<TStaffAttendance> attendanceList = initOneAttendance(staffId, staffName, storeId, storeName, managerId, mondayDate);
        int rows = staffAttendanceMapper.batchInsertForInit(attendanceList);
        return rows;
    }

    @Override
    public List<TStaffAttendance> initOneAttendance(Long staffId, String staffName, Long storeId, String storeName, Long managerId, Date mondayDate) {
        List<TStaffAttendance> attendanceList = new ArrayList<>();
        for (int i = 0; i <= 6; i++) {
            TStaffAttendance attendance = new TStaffAttendance();
            attendance.setEnable(true);
            attendance.setStaffId(staffId);
            attendance.setStaffName(staffName);
            attendance.setStoreId(storeId);
            attendance.setStoreName(storeName);
            attendance.setManagerId(managerId);
            Calendar cal = Calendar.getInstance();
            cal.setTime(mondayDate);
            cal.add(Calendar.DATE, i);
            attendance.setDate(cal.getTime());
            attendance.setStatus(false);
            attendance.setCreator(managerId);
            attendanceList.add(attendance);
        }
        return attendanceList;
    }

    /**
     * @description 批量排班 目前前端只会传一个元素
     * @Date 2019-04-23 11:12:00
     * @Param [attendanceList]
     * @return com.xingkeduo.util.tool.ResponseMessage
     **/
    @Override
    public ResponseMessage updateStaffWorkTime(List<TStaffAttendance> attendanceList) {

        log.info(attendanceList.get(0).toString());
        //如果回传的列表为空 返回0
        if (attendanceList == null || attendanceList.isEmpty()) {
            return ResponseMessage.error("数据为空", 500);
        }
        TStaffAttendance staffAttendance = attendanceList.get(0);

        Long storeId = staffAttendance.getStoreId();

        TStoreWorkPlan workPlan = storePlanService.getStorePlanByStoreId(storeId);
        if(null==workPlan){
            return ResponseMessage.error("班次还未设置,请先设置班次再排班",500);
        }
        //TODO 后期代替为接口  此处 2019-04-25 已经调整为接口获取数据
        ShopInfoVo shopInfoVo = otherService.getShopInfoByShopId(storeId);
        if(null == shopInfoVo){
            return ResponseMessage.error("未获取到相关店铺信息", 500);
        }
        List<ShopBusinessInfoVo> shopBusinessInfoVos = shopInfoVo.getDaysList();

        if(null ==shopBusinessInfoVos || shopBusinessInfoVos.size() == 0){
            return ResponseMessage.error("未获取到相关店铺营业时间信息",500);
        }
        //获取最长服务时间  注意接口返回的是分 后面处理的时候是秒
        Integer intervalTime = shopInfoVo.getParticle() * 60;
        //获取店铺座位数
        Integer seatNum = shopInfoVo.getSeatNum();

        if(intervalTime == null || seatNum == null){
            return ResponseMessage.error("店铺信息缺少最长服务时间 or 店铺座位数", 500);
        }
        //1.查出当前库存为平移做准备
        List<TStaffStock> staffStocks = staffStockService.getEnableStockListByDateAndStoreIdAndStaffId(staffAttendance.getDate(), staffAttendance.getStoreId(), staffAttendance.getStaffId());

//        for(TStaffStock staffStock : staffStocks){
//            log.info(staffStock.toString());
//        }

        List<TStaffStock> staffStockList = new ArrayList<>();
        for (TStaffAttendance attendance : attendanceList) {
            AttendanceTypeEnum typeEnum = AttendanceTypeEnum.getAttendanceType(attendance.getType());
            if (AttendanceTypeEnum.ALL_DAY_SHIFT.equals(typeEnum)) {
                attendance.setStartTime(workPlan.getAllDayShiftStartTime());
                attendance.setEndTime(workPlan.getAllDayShiftEndTime());
            }
            if (AttendanceTypeEnum.MORNING_SHIFT.equals(typeEnum)) {
                attendance.setStartTime(workPlan.getMorningShiftStartTime());
                attendance.setEndTime(workPlan.getMorningShiftEndTime());
            }
            if (AttendanceTypeEnum.NIGHT_SHIFT.equals(typeEnum)) {
                attendance.setStartTime(workPlan.getNightShiftStartTime());
                attendance.setEndTime(workPlan.getNightShiftEndTime());
            }
            //如果排班类型是 病假,事假,无排班,支援 则清空对应库存 修改考勤状态 并把考勤时间
            if(AttendanceTypeEnum.SICK_LEAVE.equals(typeEnum) ||
                    AttendanceTypeEnum.PERSONAL_LEAVE.equals(typeEnum) ||
                    AttendanceTypeEnum.NO_SCHEDULE.equals(typeEnum) ||
                    AttendanceTypeEnum.ASSIST.equals(typeEnum)) {
                //TODO 待修改为根据营业时间+1 min setStartTime
                attendance.setStartTime(CustomDateFormat.instance.parse("00:00"));
                attendance.setEndTime(CustomDateFormat.instance.parse("00:00"));
            }
            attendance.setStatus(false);
            attendance.setEnable(true);
            //计算当天是周几
            Integer dayNum = TimeUtil.getWeekDayForDate(attendance.getDate());

            Calendar endCalendar = Calendar.getInstance();
            //当天 已在店人数
//            Integer alreadyStaffNumInStore = staffStockService.getStaffNumInShop(attendance.getDate(), attendance.getStoreId());
//            if (alreadyStaffNumInStore >= seatNum + 2) {
//                return ResponseMessage.error("添加人员失败,人员数不得超过座位数2个");
//            }

            ShopBusinessInfoVo shopBusinessInfoVo = null;
            for(ShopBusinessInfoVo shopTime : shopBusinessInfoVos){
                byte daytype = shopTime.getDaytype();
                if(daytype == 1){
                    shopBusinessInfoVo = shopTime;
                }
            }

            //TODO 生成对应的库存
//            for (ShopBusinessInfoVo shopTime : shopBusinessInfoVos) {
                Boolean falg = shopBusinessInfoVo.getDayids().contains(dayNum.toString());
                if(!falg){
                    return ResponseMessage.error("当天不是上班时间，请核实后重新排班", 500);
                }else{
                    Date storeStartTime = CustomDateFormat.instance.parse(shopBusinessInfoVo.getStarttime());
                    Date storeEndTime = CustomDateFormat.instance.parse(shopBusinessInfoVo.getEndtime());
                    Date stockStartTime = attendance.getStartTime().before(storeStartTime) ? storeStartTime : attendance.getStartTime();
                    Date stockEndTime = attendance.getEndTime().after(storeEndTime) ? storeEndTime : attendance.getEndTime();
                    //对比库存生成时间段是否合理
                    log.info("stockEndTime---->>>"+stockEndTime);
                    log.info("stockStartTime---->>>"+stockStartTime);
                    log.info("stockEndTime.before(stockStartTime)--->>>"+stockEndTime.before(stockStartTime));
                    if (stockEndTime.before(stockStartTime)
                            &&
                            (!AttendanceTypeEnum.SICK_LEAVE.equals(typeEnum) &&
                            !AttendanceTypeEnum.PERSONAL_LEAVE.equals(typeEnum) &&
                            !AttendanceTypeEnum.NO_SCHEDULE.equals(typeEnum) &&
                            !AttendanceTypeEnum.ASSIST.equals(typeEnum))
                    ) {
                        return ResponseMessage.error("排班不在营业时间段内，请核实后重新排班", 500);
                    }
                    int i = staffAttendanceMapper.batchUpdateForArrange(attendanceList);
                    if (i <= 0) {
                        return ResponseMessage.error("没有需要被修改的数据", 500);
                    }
                    if (i != attendanceList.size()) {
                        return ResponseMessage.error("存在异常数据", 500);
                    }
                    endCalendar.setTime(stockStartTime);
//                    endCalendar.set(1970,1,1);
                    while (endCalendar.getTime().before(stockEndTime)) {
                        TStaffStock staffStock = new TStaffStock();
                        staffStock.setCreator(attendance.getCreator());
                        staffStock.setAttendanceId(attendance.getId());
                        staffStock.setStaffId(attendance.getStaffId());
                        staffStock.setDate(attendance.getDate());
                        staffStock.setStoreId(attendance.getStoreId());
                        staffStock.setWorkPlanId(workPlan.getId());
                        staffStock.setStartTime((Date) endCalendar.getTime().clone());
                        endCalendar.add(Calendar.SECOND, intervalTime);
                        staffStock.setEndTime((Date) endCalendar.getTime().clone());
                        staffStock.setStatus(StockStatusEnum.FREE.getValue());
                        //如果当前已经有座位数+1个人了 当前人将自动置为全部休息 人工安排
//                        if (alreadyStaffNumInStore >= seatNum + 1) {
//                            staffStock.setStatus(StockStatusEnum.SYSTEM_OCCUPY.getValue());
//                        }

                        staffStockList.add(staffStock);
                    }

                    //todo 判断是否需要休息操作
//                    //当前已在店人数
//                    Integer alreadyStaffNumInStore = staffStockService.getStaffNumInShop(attendance.getDate(), attendance.getStoreId());
//                    if (alreadyStaffNumInStore.equals(seatNum)) {
//                        //todo 休息操作(新插入的修改状态,读取老的数据到内存,进行修改,update)
//                        //如果工位数小于等于3 休息库存数 2小时/时间颗粒粒度 进一法
//                        //大于3个座位 休息库存数 1小时/时间颗粒粒度 进一法
//                        //当前策略 适用于多一人情况 多人需另作安排
//                        int restNum = 0;
//                        if (seatNum <= 3) {
//                            restNum = (int) (2 * 60 * 60 / intervalTime) + 1;
//                        } else {
//                            restNum = (int) (60 * 60 / intervalTime) + 1;
//                        }
//                        List<TStaffStock> alreadyStockList =
//                                staffStockService.getEnableStockListByDateAndStoreId(attendance.getDate(), attendance.getStoreId());
////                        alreadyStockList.sort(comparing(TStaffStock::getStaffId).thenComparing(TStaffStock::getStartTime));
//                        Set<Long> staffIdSet = new HashSet<>();
//                        for (TStaffStock staffStock : alreadyStockList) {
//                            staffIdSet.add(staffStock.getStaffId());
//                        }
//                        List<Long> staffIdList = new ArrayList<>(staffIdSet);
//                        List<Long> stockListForUpdate = new ArrayList<>();
//                        Date earliestStartTime = earliestStartTime(staffStockList);
//                        stockListForUpdate = isNeedToRestForTime(staffStockList, stockListForUpdate, staffIdList, earliestStartTime, seatNum, 0, restNum, intervalTime);
//
//
//                    }
                }
            }

//        }

        //3.清空对应库存
        int delectRows=-1, insertRows=-1, updateRows=-1;
//        delectRows = staffStockService.deleteStockByDateAndstaffId(staffAttendance.getDate(), staffAttendance.getStaffId());
        delectRows = staffStockService.deleteStockByDateAndstaffIdAndStoreId(staffAttendance.getDate(), staffAttendance.getStaffId(), staffAttendance.getStoreId());
        if (!staffStockList.isEmpty()) {
            //TODO 因为BaBar占用双库存逻辑的存在 平移之前需要预处理一下
            List<TStaffStock> staffStocks1 = babarStockPretreatment(staffStocks, staffStockList, staffAttendance.getType());
            //4.平移库存
            List<TStaffStock> newStockListAfterMove = staffStockService.getNewStockListAfterMove(staffStocks1, staffStockList);
            insertRows = staffStockService.batchInsertStaffStock(newStockListAfterMove);
        }
        //2.当天排班库存人数
        Integer alreadyStaffNumInStoreTotal = staffStockService.getStaffNumInShop(staffAttendance.getDate(), staffAttendance.getStoreId());
            //5.把排班时间当天店铺下所有系统占用的库存全部置为可用
            updateRows = staffStockService.updateStockStatusByStoreIdAndDate(staffAttendance.getDate(), staffAttendance.getStoreId());

        //6.执行自动休息逻辑
        if (delectRows >= 0 | insertRows >= 0 | updateRows >= 0) {
            makeRestStatusBySystem(storeId, staffAttendance.getDate(), intervalTime, alreadyStaffNumInStoreTotal, seatNum);
        }
        rabbitMqSender.sendMessage("websocket_transfer_exchange", "websocket_transfer_key", JSON.toJSONString(new WebsocketMessageResponse<>(WORKPAD, String.valueOf(storeId), null)));
        return ResponseMessage.ok("排班成功");
    }

    /**
     * @description  查找重新排班受影响的订单
     * @Author 情绪极其不稳定的Shadow
     * @Param [staffAttendance]
     * @return com.xingkeduo.util.tool.ResponseMessage
     **/
    @Override
    public ResponseMessage getImpactOrderByScheduling(TStaffAttendance staffAttendance) {
        //如果回传的列表为空 返回0
        if (staffAttendance == null) {
            return ResponseMessage.error("数据为空", 500);
        }
        Long storeId = staffAttendance.getStoreId();

        TStoreWorkPlan workPlan = storePlanService.getStorePlanByStoreId(storeId);
        if(null==workPlan){
            return ResponseMessage.error("班次还未设置,请先设置班次再排班",500);
        }
        ShopInfoVo shopInfoVo = otherService.getShopInfoByShopId(storeId);
        if(null == shopInfoVo){
            return ResponseMessage.error("未获取到相关店铺信息", 500);
        }
        List<ShopBusinessInfoVo> shopBusinessInfoVos = shopInfoVo.getDaysList();

        if(null ==shopBusinessInfoVos || shopBusinessInfoVos.size() == 0){
            return ResponseMessage.error("未获取到相关店铺营业时间信息",500);
        }
        //获取最长服务时间  注意接口返回的是分 后面处理的时候是秒
        Integer intervalTime = shopInfoVo.getParticle() * 60;
        //获取店铺座位数
        Integer seatNum = shopInfoVo.getSeatNum();

        if(intervalTime == null || seatNum == null){
            return ResponseMessage.error("店铺信息缺少最长服务时间 or 店铺座位数", 500);
        }
        //1.查出当前库存为平移做准备
        List<TStaffStock> staffStocks = staffStockService.getEnableStockListByDateAndStoreIdAndStaffId(staffAttendance.getDate(), staffAttendance.getStoreId(), staffAttendance.getStaffId());
        List<TStaffStock> staffStockList = new ArrayList<>();
        AttendanceTypeEnum typeEnum = AttendanceTypeEnum.getAttendanceType(staffAttendance.getType());
        if (AttendanceTypeEnum.ALL_DAY_SHIFT.equals(typeEnum)) {
            staffAttendance.setStartTime(workPlan.getAllDayShiftStartTime());
            staffAttendance.setEndTime(workPlan.getAllDayShiftEndTime());
        }
        if (AttendanceTypeEnum.MORNING_SHIFT.equals(typeEnum)) {
            staffAttendance.setStartTime(workPlan.getMorningShiftStartTime());
            staffAttendance.setEndTime(workPlan.getMorningShiftEndTime());
        }
        if (AttendanceTypeEnum.NIGHT_SHIFT.equals(typeEnum)) {
            staffAttendance.setStartTime(workPlan.getNightShiftStartTime());
            staffAttendance.setEndTime(workPlan.getNightShiftEndTime());
        }
        //如果排班类型是 病假,事假,无排班,支援 则清空对应库存 修改考勤状态 并把考勤时间
        if(AttendanceTypeEnum.SICK_LEAVE.equals(typeEnum) ||
                AttendanceTypeEnum.PERSONAL_LEAVE.equals(typeEnum) ||
                AttendanceTypeEnum.NO_SCHEDULE.equals(typeEnum) ||
                AttendanceTypeEnum.ASSIST.equals(typeEnum)) {
            //TODO 待修改为根据营业时间+1 min setStartTime
            staffAttendance.setStartTime(CustomDateFormat.instance.parse("00:00"));
            staffAttendance.setEndTime(CustomDateFormat.instance.parse("00:00"));
        }
        staffAttendance.setStatus(false);
        staffAttendance.setEnable(true);
        //计算当天是周几
        Integer dayNum = TimeUtil.getWeekDayForDate(staffAttendance.getDate());

        Calendar endCalendar = Calendar.getInstance();
        ShopBusinessInfoVo shopBusinessInfoVo = null;
        for(ShopBusinessInfoVo shopTime : shopBusinessInfoVos){
            byte daytype = shopTime.getDaytype();
            if(daytype == 1){
                shopBusinessInfoVo = shopTime;
            }
        }

        Boolean falg = shopBusinessInfoVo.getDayids().contains(dayNum.toString());
        if(!falg){
            return ResponseMessage.error("当天不是上班时间，请核实后重新排班", 500);
        }else{
            Date storeStartTime = CustomDateFormat.instance.parse(shopBusinessInfoVo.getStarttime());
            Date storeEndTime = CustomDateFormat.instance.parse(shopBusinessInfoVo.getEndtime());
            Date stockStartTime = staffAttendance.getStartTime().before(storeStartTime) ? storeStartTime : staffAttendance.getStartTime();
            Date stockEndTime = staffAttendance.getEndTime().after(storeEndTime) ? storeEndTime : staffAttendance.getEndTime();
            //对比库存生成时间段是否合理
            if (stockEndTime.before(stockStartTime)
                    &&
                    (!AttendanceTypeEnum.SICK_LEAVE.equals(typeEnum) &&
                            !AttendanceTypeEnum.PERSONAL_LEAVE.equals(typeEnum) &&
                            !AttendanceTypeEnum.NO_SCHEDULE.equals(typeEnum) &&
                            !AttendanceTypeEnum.ASSIST.equals(typeEnum))
            ) {
                return ResponseMessage.error("排班不在营业时间段内，请核实后重新排班", 500);
            }
            endCalendar.setTime(stockStartTime);
            while (endCalendar.getTime().before(stockEndTime)) {
                TStaffStock staffStock = convers(staffAttendance, workPlan, endCalendar, intervalTime);
                staffStockList.add(staffStock);
            }
        }
        //受影响的订单号
        List<Long> disappearOrderIds = new ArrayList<>();
        //受影响的订单集合
        List<String> orderIdList = new ArrayList<>();
        //受影响的订单数组
        String [] orderNos = null;
        //原库存订单Ids
        List<Long> orderIds = new ArrayList<>();
        //平移之后订单Ids
        List<Long> newOrderIds = new ArrayList<>();
        for(TStaffStock staffStock : staffStocks){
            if(!StringUtils.isEmpty(staffStock.getOrderId())){
                if(staffStock.getStatus() == 2){
                    orderIds.add(staffStock.getOrderId());
                }
            }
        }
        log.info("orderIds平移之后待服务的订单Id--->"+orderIds.toString());
        log.info("orderIds平移之后待服务的订单Id---size>"+orderIds.size());
        if (!staffStockList.isEmpty()) {
            //TODO 因为BaBar占用双库存逻辑的存在 平移之前需要预处理一下
            List<TStaffStock> staffStocks1 = babarStockPretreatment(staffStocks, staffStockList, staffAttendance.getType());
            //4.平移库存
            // staffStocks 原库存  staffStockList 新库存  newStockListAfterMove平移之后的新库存
            List<TStaffStock> newStockListAfterMove = staffStockService.getNewStockListAfterMove(staffStocks1, staffStockList);
            for(TStaffStock staffStock : newStockListAfterMove){
                if(!StringUtils.isEmpty(staffStock.getOrderId())){
                    if(staffStock.getStatus() == 2){
                        newOrderIds.add(staffStock.getOrderId());
                    }
                }
            }
            for(Long orderId : orderIds){
                boolean contains = newOrderIds.contains(orderId);
                if(!contains){
                    disappearOrderIds.add(orderId);
                }
            }
        }else{
            for(Long orderId : orderIds){
                disappearOrderIds.add(orderId);
            }
        }
        log.info("disappearOrderIds重新排班之后需要提示的订单Id--->>>"+disappearOrderIds.toString());
        log.info("disappearOrderIds重新排班之后需要提示的订单Id---size>>>"+disappearOrderIds.size());
        if(!CollectionUtils.isEmpty(disappearOrderIds)){
            for(Long orderId: disappearOrderIds){
                orderIdList.add(String.valueOf(orderId));
            }
            orderNos = orderIdList.toArray(new String[orderIdList.size()]);
        }
        //2.根据订单ID去订单系统查询订单详情
        List<OrderInfoVo> orderInfos = otherService.getOrderInfoByOrderNos(orderNos);
        if(CollectionUtils.isEmpty(orderInfos)){
            return ResponseMessage.ok("此次排班操作不会有收到影响的订单");
        }
        for(OrderInfoVo vo : orderInfos){
            log.info("受影响的订单ID--->>>"+vo.getOrderNo());
            log.info("受影响的订单用户手机号--->>>"+vo.getUserMobile());
            log.info("受影响的订单时间--->>>"+vo.getAppointmentStartTime());
            log.info("受影响的订单排队号--->>>"+vo.getWaitingLineNo());
        }
        return ResponseMessage.ok(orderInfos);
    }

    /**
     * @description  判断系统自动休息
     * @TODO 上线完成后 考虑搬回库存服务里
     * @param storeId 店铺id
     * @param attendanceDate 排班日期
     * @param intervalTime 最大服务时长 库存颗粒
     * @param alreadyStaffNumInStore  店铺下绑定发型师总数
     * @param seatNum  店铺下工位数
     */
    @Override
    public void makeRestStatusBySystem(Long storeId, Date attendanceDate, Integer intervalTime, Integer alreadyStaffNumInStore, Integer seatNum) {
        log.info("storeId 店铺id--->>>"+storeId);
        log.info("attendanceDate 排班日期--->>>"+attendanceDate);
        log.info("intervalTime 库存颗粒--->>>"+intervalTime);
        log.info("alreadyStaffNumInStore  店铺下绑定发型师总数--->>>"+alreadyStaffNumInStore);
        log.info("eatNum  店铺下工位数--->>>"+seatNum);
        //获取店铺座位数
        //TODO 换成接口 此处 2019-04-25 换成参数传递
//        Integer seatNum = shopInfoService.getSeatNumByShopId(storeId);
        if (alreadyStaffNumInStore <= seatNum) {
            return;
        }
        if (alreadyStaffNumInStore > seatNum) {
            //todo 休息操作(新插入的修改状态,读取老的数据到内存,进行修改,update)
            //如果工位数小于等于3 休息库存数 2小时/时间颗粒粒度 进一法
            //大于3个座位 休息库存数 1小时/时间颗粒粒度 进一法
            //当前策略 适用于多一人情况 多人需另作安排
            int restNum = 0;
            if (seatNum <= 3) {
                restNum = (int) (2 * 60 * 60 / intervalTime) + 1;
            } else {
                restNum = (int) (60 * 60 / intervalTime) + 1;
            }
            List<TStaffStock> alreadyStockList =
                    staffStockService.getEnableStockListByDateAndStoreId(attendanceDate, storeId);
            alreadyStockList.sort(comparing(TStaffStock::getId));
            Set<Long> staffIdSet = new HashSet<>();
            List<Long> staffIdList = new ArrayList<>();
            for (TStaffStock staffStock : alreadyStockList) {
                if (!staffIdSet.contains(staffStock.getStaffId())) {
                    staffIdSet.add(staffStock.getStaffId());
                    staffIdList.add(staffStock.getStaffId());
                }
            }
            Collections.reverse(staffIdList);
            List<Long> stockListForUpdate = new ArrayList<>();
            Date earliestStartTime = earliestStartTime(alreadyStockList);
            stockListForUpdate =
                    isNeedToRestForTime(getNeedToRestStock(alreadyStockList,staffIdList,seatNum), stockListForUpdate, staffIdList, earliestStartTime, seatNum, 0, restNum, intervalTime);
            List<Long> moreThanTwoStockIdList = getMoreThanTwoStaffStockIdList(staffIdList, alreadyStockList, seatNum);
            stockListForUpdate.addAll(moreThanTwoStockIdList);
            staffStockService.updateBatchStockToSystemOccupyByIdList(stockListForUpdate);


        }
    }


    /**
     * @param staffStockList
     * @return java.util.Date
     * @description 获取最早开始时间
     * @author 中文输入法发挥不稳定的刘川
     * @date 19-4-10 下午2:57
     */
    Date earliestStartTime(List<TStaffStock> staffStockList) {
        Date res = staffStockList.get(0).getStartTime();
        for (TStaffStock stock : staffStockList) {
            if (stock.getStartTime().before(res)) {
                res = stock.getStartTime();
            }
        }
        return res;
    }

    /**
     * 当人数比座位数多2个的时候，后面所有新加人员库存置为系统占用
     *
     * @return java.util.List<java.lang.Long>
     * @author 中文输入法发挥不稳定的刘川
     * @date 19-4-22 下午5:02
     */
    List<Long> getMoreThanTwoStaffStockIdList(List<Long> staffIdList, List<TStaffStock> staffStockList, Integer seatNum) {
        List<Long> changeStockIdList = new ArrayList<>();
        if (staffIdList.size() < seatNum + 2) {
            return changeStockIdList;
        }
        List<Long> needToChangeStaffIdList = staffIdList.subList(seatNum + 1, staffIdList.size());
        for (TStaffStock staffStock : staffStockList) {
            if (needToChangeStaffIdList.contains(staffStock.getStaffId())) {
                changeStockIdList.add(staffStock.getId());
            }
        }
        return changeStockIdList;
    }

    /**
     * @param allStockList
     * @param staffIdList
     * @return java.util.List<com.xingkeduo.model.po.TStaffStock>
     * 截取需自动休息的库存
     * @author 刘川的英文名是luke
     * @date 19-7-30 下午3:24
     */
    List<TStaffStock> getNeedToRestStock(List<TStaffStock> allStockList, List<Long> staffIdList, Integer seatNum) {
        List<Long> needToChangeStaffIdList = staffIdList.subList(0,seatNum + 1);
        List<TStaffStock> needToRestStockList = new ArrayList<>();
        for (TStaffStock staffStock : allStockList) {
            if (needToChangeStaffIdList.contains(staffStock.getStaffId())) {
                needToRestStockList.add(staffStock);
            }
        }
        return needToRestStockList;
    }


    /**
     * @param staffStockList
     * @param idList
     * @param staffIdList
     * @param startTime
     * @param seatNum
     * @param iRest
     * @param restNum
     * @param timeInterval
     * @return java.util.List<java.lang.Long>
     * @description 之所以这么每次都判断一次当前时间段 不是连续1小时 是因为未来时间5分钟判断一次 应对以后每个人时间颗粒不同的情况
     * @author 中文输入法发挥不稳定的刘川
     * @date 19-4-10 下午2:19
     */
    List<Long> isNeedToRestForTime(List<TStaffStock> staffStockList, List<Long> idList, List<Long> staffIdList, Date startTime, int seatNum, int iRest, int restNum, int timeInterval) {
        int num = 0;
        //判断到23点 为递归结束条件
        if (startTime.getHours() >= 23) {
            return idList;
        }

        //判断当前时段的库存量
        for (TStaffStock staffStock : staffStockList) {
            if (staffStock.getStartTime().equals(startTime)) {
                num++;
            }
//            log.info("Time："+startTime.toString()+"=====>此时间库存量："+num);
        }

        //判断当前时段的库存量是不是超过座位数
        if (num >= seatNum + 1) {
            int foundNo = 0;
            Boolean isFound = false;
            for (TStaffStock staffStock : staffStockList) {

                //找到该休息的人
                int restStaffNo = (iRest / restNum) % staffIdList.size();
                if (restStaffNo > seatNum) {
                    iRest = 0;
                }
                if (staffStock.getStaffId().equals(staffIdList.get((iRest / restNum) % staffIdList.size())) && staffStock.getStartTime().equals(startTime)) {
                    isFound = true;
                    iRest++;
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(startTime);
                    calendar.add(Calendar.SECOND, timeInterval);
                    if (staffStock.getStatus().equals(StockStatusEnum.FREE.getValue())) {
                        idList.add(staffStock.getId());
                    }
                    idList = isNeedToRestForTime(staffStockList, idList, staffIdList, calendar.getTime(), seatNum, iRest, restNum, timeInterval);
                    break;
                }

            }

            //如果没找到就从下个人哪里找
            if (!isFound) {
                log.info("stock not found for No."+(iRest / restNum) % staffIdList.size()+"====>>StaffId:"+staffIdList.get((iRest / restNum) % staffIdList.size()));
                iRest = iRest + restNum;
                idList = isNeedToRestForTime(staffStockList, idList, staffIdList, startTime, seatNum, iRest, restNum, timeInterval);
            }


            return idList;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.SECOND, timeInterval);
        idList = isNeedToRestForTime(staffStockList, idList, staffIdList, calendar.getTime(), seatNum, iRest, restNum, timeInterval);
        return idList;
    }


    /**
     * @return java.util.List<com.xingkeduo.model.vo.StaffAttendanceVo>
     * @description 获取传入时间段排班情况
     * @Author 情绪极其不稳定的Shadow
     * @Param [selectedDate]
     **/
    @Override
    public Map<Long,StaffAttendanceSummaryVo> getStaffAttendance(String selectedDate, Long storeId, Long staffId){
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dateOfMonday = null;
        Date dateOfSunday = null;
        //判断是否传入时间 根据时间获取当前周 周一 周日 日期
        if (StringUtils.isEmpty(selectedDate)) {
            dateOfMonday = TimeUtil.getDateOfMonday(new Date(), 0);
            dateOfSunday = TimeUtil.getDateOfSunday(dateOfMonday);
        } else {
            try {
                Date date = simdf.parse(selectedDate);
                dateOfMonday = TimeUtil.getDateOfMonday(date, 0);
                dateOfSunday = TimeUtil.getDateOfSunday(dateOfMonday);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        String formatDateOfMonday = simdf.format(dateOfMonday);
        String formatDateOfSunday = simdf.format(dateOfSunday);

        List<TStaffAttendance> staffAttendances = staffAttendanceMapper.selectBySelectedDate(
                formatDateOfMonday, formatDateOfSunday, storeId, staffId);
        List<StaffAttendanceVo> listVo = new ArrayList<>();
        Map<Long, StaffAttendanceSummaryVo> map = new LinkedHashMap<>();

        //准备数据
        List<Long> staffIds = new ArrayList<>();
        for(TStaffAttendance attendance : staffAttendances){
            staffIds.add(attendance.getStaffId());
        }
        Set setStaffId = new HashSet(staffIds);
        List<Long> staffIdList = new ArrayList<>(setStaffId);
        List<StaffInfoVo> staffInfoVoList = otherService.getStaffInfoVo(staffIdList);
        if (!CollectionUtils.isEmpty(staffAttendances)) {
            for (TStaffAttendance staffAttendance : staffAttendances) {
                if(!CollectionUtils.isEmpty(staffInfoVoList)){
                    for(StaffInfoVo staffInfoVo : staffInfoVoList){
                        if(staffInfoVo.getJobseekerId().equals(staffAttendance.getStaffId())){
                            StaffAttendanceVo vo = new StaffAttendanceVo(staffAttendance, staffInfoVo.getCode());
                            listVo.add(vo);
                        }
                    }
                }else {
                    StaffAttendanceVo vo = new StaffAttendanceVo(staffAttendance, null);
                    listVo.add(vo);
                }
            }

            for (StaffAttendanceVo vo : listVo) {
                if (map.containsKey(vo.getStaffId())) {
                    map.get(vo.getStaffId()).setStaffId(vo.getStaffId());
                    map.get(vo.getStaffId()).setStaffName(vo.getStaffName());
                    map.get(vo.getStaffId()).getList().add(vo);
                } else {
                    map.put(vo.getStaffId(), new StaffAttendanceSummaryVo(vo.getStaffId(), vo.getStaffName(), new ArrayList<>()));
                    map.get(vo.getStaffId()).getList().add(vo);
                }
            }
        }

        return map;
    }

    /**
     * @return java.util.List<com.xingkeduo.model.po.TStaffAttendance>
     * @description 根据发型师ID 时间 查找发型师当天对应店铺排班
     * @Author 情绪极其不稳定的Shadow
     * @Param [staffId, date]
     **/
    @Override
    public List<StaffAttendanceVo> getStaffAttendanceByStaffId(Long staffId, String date) {
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        Date newDate = null;
        if (StringUtils.isEmpty(date)) {
            newDate = new Date();
            date = simdf.format(newDate);
        }
        List<TStaffAttendance> staffAttendances = staffAttendanceMapper.selectByStaffIAndDate(staffId, date);
        List<StaffAttendanceVo> voList = new ArrayList<>();
        for(TStaffAttendance staffAttendance : staffAttendances){
            StaffAttendanceVo vo = new StaffAttendanceVo(staffAttendance, null);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * @return java.util.List<com.xingkeduo.model.vo.StaffAttendanceVo>
     * @description 获取当天店铺所有发型师打卡信息
     * @Author 情绪极其不稳定的Shadow
     * @Param [storeId]
     **/
    @Override
    public StoreAttendanceVo getStaffAttendanceByStoreId(Long storeId) {
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        String selectDate = simdf.format(new Date());
        List<TStaffAttendance> attendances = staffAttendanceMapper.selectStaffAttendanceByStoreId(storeId, selectDate);
        //准备数据
        List<Long> staffIds = new ArrayList<>();
        for(TStaffAttendance attendance : attendances){
            staffIds.add(attendance.getStaffId());
        }
        Set setStaffId = new HashSet(staffIds);
        List<Long> staffIdList = new ArrayList<>(setStaffId);
        List<StaffInfoVo> staffInfoVoList = otherService.getStaffInfoVo(staffIdList);

        //生成上班考勤列表 TODO 头像Url还未添加 2019-04-18 15:48 以实现
        List<StartAttendanceVo> startAttendanceVos = new ArrayList<>();
        for(TStaffAttendance attendance : attendances){
            if(!CollectionUtils.isEmpty(staffInfoVoList)){
                for(StaffInfoVo staffInfoVo : staffInfoVoList){
                    if(staffInfoVo.getJobseekerId().equals(attendance.getStaffId())){
                        StartAttendanceVo vo = new StartAttendanceVo(attendance, staffInfoVo.getPath(), staffInfoVo.getCraftsName());
                        startAttendanceVos.add(vo);
                    }
                }
            }else{
                StartAttendanceVo vo = new StartAttendanceVo(attendance, "", "");
                startAttendanceVos.add(vo);
            }

        }
        //生成下班考勤列表
        List<EndAttendanceVo> endAttendanceVos = new ArrayList<>();
        for(TStaffAttendance attendance : attendances){
            if(!CollectionUtils.isEmpty(staffInfoVoList)){
                for(StaffInfoVo staffInfoVo : staffInfoVoList){
                    if(staffInfoVo.getJobseekerId().equals(attendance.getStaffId())){
                        EndAttendanceVo vo = new EndAttendanceVo(attendance, staffInfoVo.getPath(), staffInfoVo.getCraftsName());
                        endAttendanceVos.add(vo);
                    }
                }
            }else {
                EndAttendanceVo vo = new EndAttendanceVo(attendance, "", "");
                endAttendanceVos.add(vo);
            }

        }
        StoreAttendanceVo storeAttendanceVo = new StoreAttendanceVo();
        storeAttendanceVo.setStartAttendanceVos(startAttendanceVos);
        storeAttendanceVo.setEndAttendanceVos(endAttendanceVos);
        return storeAttendanceVo;
    }

    /**
     * @return java.util.List<com.xingkeduo.model.vo.StaffAttendanceVo>
     * @description 发型师考勤列表
     * @Author 情绪极其不稳定的Shadow
     * @Param [param]
     **/
    @Override
    public List<StaffAttendanceVo> getAttendanceOfPersonal(AttendanceParam param) {
        if(null == param.getEndTime()){
            param.setEndTime(new Date());
        }
        List<TStaffAttendance> attendances = staffAttendanceMapper.selectAttendanceOfPersonal(param);
        List<StaffAttendanceVo> voList = new ArrayList<>();
        if (attendances.size() == 0) {
            return null;
        }
        for (TStaffAttendance attendance : attendances) {
            if(attendance.getType() != 6){
                StaffAttendanceVo vo = new StaffAttendanceVo(attendance, null);
                voList.add(vo);
            }
        }
        //迟早退 旷工 状态赋值
        for(StaffAttendanceVo vo : voList){
            if(StringUtils.isEmpty(vo.getRealWorkStartTime()) && StringUtils.isEmpty(vo.getRealWorkStopTime())){
                vo.setWorkStatus(String.valueOf(AttendanceWorkStatusEnum.ABSENTEEISM_TIME.getValue()));
            }
//            else if(vo.getStartTime().before(vo.getRealWorkStartTime()) && vo.getEndTime().before(vo.getRealWorkStopTime())){
//                vo.setWorkStatus(AttendanceWorkStatusEnum.LATE_TIME.getDesc());
//            }else if(vo.getRealWorkStartTime().before(vo.getStartTime()) && vo.getRealWorkStopTime().before(vo.getEndTime())){
//                vo.setWorkStatus(AttendanceWorkStatusEnum.LEAVE_EARLY_TIME.getDesc());
//            }else if(vo.getStartTime().before(vo.getRealWorkStartTime()) && vo.getRealWorkStopTime().before(vo.getEndTime())){
//                vo.setWorkStatus(AttendanceWorkStatusEnum.LATE_LEAVE_EARLY_TIME.getDesc());
//            }else{
//                vo.setWorkStatus(AttendanceWorkStatusEnum.NORMAL_TIME.getDesc());
//            }
        }
        return voList;
    }

    /**
     * @description  根据店铺id查询 店铺下绑定员工 总排班天数 and 发型师部分信息
     * @Author 情绪极其不稳定的Shadow
     * @Param [storeId]
     * @return java.util.List<com.xingkeduo.model.vo.StaffSchedulingVo>
     **/
    @Override
    public List<StaffSchedulingVo> getStaffSchedulingByStoreId(Long storeId) {
        String selectDate = TimeUtil.DateToFormat(new Date(), "yyyy-MM-dd");
        List<StaffSchedulingVo> staffSchedulingVos = staffAttendanceMapper.selectStaffSchedulingByStoreId(storeId, selectDate);
        if(CollectionUtils.isEmpty(staffSchedulingVos)){
            return staffSchedulingVos;
        }
        //准备数据
        List<Long> staffIds = new ArrayList<>();
        for(StaffSchedulingVo vo : staffSchedulingVos){
            staffIds.add(vo.getStaffId());
        }
        Set setStaffId = new HashSet(staffIds);
        List<Long> staffIdList = new ArrayList<>(setStaffId);
        List<StaffInfoVo> staffInfoVo = otherService.getStaffInfoVo(staffIdList);
        //TODO 调用户系统接口 获取头像 工号 合并处理返回 目前未处理 2019-05-03 已处理
        if(!CollectionUtils.isEmpty(staffInfoVo)){
            for(StaffSchedulingVo staffSchedulingVo : staffSchedulingVos){
                for(StaffInfoVo infoVo : staffInfoVo){
                    if(infoVo.getJobseekerId().equals(staffSchedulingVo.getStaffId())){
                        staffSchedulingVo.setCraftsCode(infoVo.getCode());
                        staffSchedulingVo.setHeadUrl(infoVo.getPath());
                    }
                }
            }
        }
        return staffSchedulingVos;
    }
    
    /**
     * @description  获取发型师id 获取所有店铺总排班天数 and 店铺名称
     * @Author 情绪极其不稳定的Shadow
     * @Param [staffId]
     * @return java.util.List<com.xingkeduo.model.vo.StoreSchedulingVo>
     **/
    @Override
    public List<StoreSchedulingVo> getStoreSchedulingByStaffId(Long staffId, String storeName) {
        String selectDate = TimeUtil.DateToFormat(new Date(), "yyyy-MM-dd");
        return staffAttendanceMapper.selectStoreSchedulingByStaffId(staffId, storeName, selectDate);
    }

    @Override
    public ResponseMessage unableStaffAttendanceByStoreIdAndStaffIdAndWeek(Long storeId, Long staffId, Date weekDay) {
        String result = "";
        List<Date> dateList = new ArrayList<>();
        for (int i = 0; i <= 6; i++) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(weekDay);
            cal.add(Calendar.DATE, i);
            dateList.add(cal.getTime());
        }
        int rows= staffAttendanceMapper.unableStaffAttendanceByStoreIdAndStaffIdAndWeek(storeId,staffId,dateList);
        if(rows>0){
            result=result+" 共有"+rows+"条排班被取消。";
        }else {
            result +="没有排班被取消";
            return ResponseMessage.error(result,500);
        }
        int rowStock= staffStockService.unableStockByStoreIdAndStaffIdAndWeek(storeId,staffId,dateList);
        if(rowStock>0){
            result += " 同时取消"+rowStock+"个库存";
        }else {
            result += "取消库存失败，请查看库存现状。";
            return ResponseMessage.error(result,500);
        }

        return ResponseMessage.ok(result);
    }

    @Override
    public int updateResetAttendanceTypeByAfterDateAndShopId(Date dateOfMonday, Long shopId, Long modifier) {
        int i = staffAttendanceMapper.updateResetAttendanceTypeByAfterDateAndShopId(dateOfMonday, shopId, modifier);
        return i;
    }

    @Override
    public int updateEmptyAttendanceTimeByAfterDateAndShopId(Date nowDate, Long shopId, Long modifier) {
        int i = staffAttendanceMapper.updateEmptyAttendanceTimeByAfterDateAndShopId(nowDate, shopId, modifier);
        return i;
    }

    @Override
    public List<StoreInfoVo> getAttendanceStoresByStaffId(Long staffId) {
        Date selectDate = new Date();
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        List<TStaffAttendance> tStaffAttendances = staffAttendanceMapper.selectAttendanceStoresByStaffId(staffId, simdf.format(selectDate));
        List<StoreInfoVo> vos = new ArrayList<>();
        for(TStaffAttendance staffAttendance : tStaffAttendances){
            StoreInfoVo vo = new StoreInfoVo();
            vo.setStoreId(staffAttendance.getStoreId());
            vo.setStoreName(staffAttendance.getStoreName());
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public int countAttendanceByStaffIdAndStoreId(Long storeId, Long staffId, Date selectDate) {
        return staffAttendanceMapper.countAttendanceByStaffIdAndStoreId(storeId, staffId, selectDate);
    }

    @Override
    public List<String> getAttendanceByStaffIdAndStoreId(Long storeId, Long staffId, String selectDate) {
        return staffAttendanceMapper.selectAttendanceByStaffIdAndStoreId(storeId, staffId, selectDate);
    }

    @Override
    public int updateAttendanceTypeByStoreId(Long storeId, String selectDate) {
        return staffAttendanceMapper.updateAttendanceTypeByStoreId(storeId, selectDate);
    }

    public List<Long> getStaffIdListSortByInsertSequence(Long storeId, Date date) {
        List<TStaffStock> staffStockIdList = staffStockService.getIdAndStaffIdByDateAndStoreId(date, storeId);
        staffStockIdList.sort(comparing(TStaffStock::getId));
        List<Long> staffIdList = new ArrayList<>();
        for (TStaffStock staffStock : staffStockIdList) {
            staffIdList.add(staffStock.getStaffId());
        }
        return staffIdList;
    }


    /**
     *
     * @author 中文输入法发挥不稳定的刘川
     * @date 19-5-8 下午6:27
    * @param storeId
    * @param staffId
     * @return int 如果-1是员工没有今天之后的排班
     */
    @Override
    public int staffStoreMaxNumberOfDays(Long storeId,Long staffId){
        Date lastDate=staffAttendanceMapper.getLastStaffAttendanceDateByStaffIdAndStoreId(storeId,staffId);
        if(null==lastDate){
            return -1;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.HOUR,0);
        Date now=calendar.getTime();
        return TimeUtil.getTwoDayLength(now,lastDate);
    }

    @Override
    public List<TStaffAttendance> getAttendanceIdByStatusAndDate(int status, String selectDate) {
        List<TStaffAttendance> staffAttendances = staffAttendanceMapper.selectAttendanceIdByStatusAndDate(status, selectDate);
        return staffAttendances;
    }

    @Override
    public int batchUpdateStatusById(List<Integer> ids) {
        int i = staffAttendanceMapper.batchUpdateStatusById(ids);
        return i;
    }

    private TStaffStock convers(TStaffAttendance staffAttendance, TStoreWorkPlan workPlan, Calendar endCalendar, Integer intervalTime){
        TStaffStock staffStock = new TStaffStock();
        staffStock.setCreator(staffAttendance.getCreator());
        staffStock.setAttendanceId(staffAttendance.getId());
        staffStock.setStaffId(staffAttendance.getStaffId());
        staffStock.setDate(staffAttendance.getDate());
        staffStock.setStoreId(staffAttendance.getStoreId());
        staffStock.setWorkPlanId(workPlan.getId());
        staffStock.setStartTime((Date) endCalendar.getTime().clone());
        endCalendar.add(Calendar.SECOND, intervalTime);
        staffStock.setEndTime((Date) endCalendar.getTime().clone());
        staffStock.setStatus(StockStatusEnum.FREE.getValue());
        return staffStock;
    }


/*    //CMS后台库存分页列表
    @Override
    public PageInfo<CmsStaffAttendancePageVo> getAttendanceList(AttendancePageParam attendancePageParam) {

        ArrayList<CmsStaffAttendancePageVo> cmsStaffAttendancePageVoList = new ArrayList<>();
//        if(attendancePageParam.getStartDate() == ""||  attendancePageParam.getStartDate() ==null&&attendancePageParam.getEndDate() == ""||attendancePageParam.getEndDate() ==null){
//            attendancePageParam.setStartDate(TimeUtil.DateToFormat(new Date(), "yyyy-MM-dd"));
//        }
        if(attendancePageParam.getStaffInfo() != null){
            List<CmsCraftsmanDTO> shopActivityList = otherService.getShopActivityList(attendancePageParam.getStaffInfo());
            if(shopActivityList !=null && shopActivityList.size() >0){
                List<Long> craftsman = new ArrayList<>();
                for (CmsCraftsmanDTO cmsCraftsmanDTO : shopActivityList) {
                    craftsman.add(cmsCraftsmanDTO.getId());
                }
                attendancePageParam.setStaffIds(craftsman);
            }
        }
        Integer pageNo = attendancePageParam.getPageNo();
        Integer pageSize = attendancePageParam.getPageSize();
        PageHelper.startPage(pageNo, pageSize);
        List<TStaffAttendance> tStaffAttendances = staffAttendanceMapper.selectStaffAttendancePageList(attendancePageParam);
        if(!CollectionUtils.isEmpty(tStaffAttendances)){
            for (TStaffAttendance tStaffAttendance : tStaffAttendances) {

                CmsStaffAttendancePageVo cmsStaffAttendancePageVo = new CmsStaffAttendancePageVo(tStaffAttendance);
                //创建发型师ID数组
                List<Long> staffIds = new ArrayList<>();
                staffIds.add(tStaffAttendance.getStaffId());
                Set setStaffId = new HashSet(staffIds);
                List staffIdList = new ArrayList(setStaffId);

                //根据发型师ID获取发型师信息
                List<StaffInfoVo> staffInfoVoList = otherService.getStaffInfoVo(staffIdList);
                if(staffInfoVoList != null && staffInfoVoList.size()>0){
                    for(StaffInfoVo infoVo : staffInfoVoList){
                        if(infoVo.getJobseekerId().equals(tStaffAttendance.getStaffId())){
                            cmsStaffAttendancePageVo.setStaffName(infoVo.getName() == null ? null :infoVo.getName());
                            cmsStaffAttendancePageVo.setStaffNickName(infoVo.getCraftsName() == null ? null :infoVo.getCraftsName());
                        }
                    }
                }
                //创建二线员工ID数组
                List<Long> modifier = new ArrayList<>();
                staffIds.add(tStaffAttendance.getModifier());
                Set modifierId = new HashSet(modifier);
                List modifierList = new ArrayList(modifierId);

                //根据二线用户信息
                List<ManagerDTO> managerList = otherService.getManagerList(modifierList);
                if(managerList != null && managerList.size()>0){
                    for (ManagerDTO managerDTO : managerList) {
                        if(tStaffAttendance.getModifier()!= null && managerDTO.getId() == tStaffAttendance.getModifier()){
                            cmsStaffAttendancePageVo.setModifierName(managerDTO.getName() == "" ? null :managerDTO.getName());
                        }
                    }
                }
                cmsStaffAttendancePageVoList.add(cmsStaffAttendancePageVo);
            }
        }

        PageInfo<CmsStaffAttendancePageVo> staffAttendancePageVoPageInfo = new PageInfo<>(cmsStaffAttendancePageVoList);
//        staffAttendancePageVoPageInfo.setPages(tStaffAttendancePageInfo.getPages());
//        staffAttendancePageVoPageInfo.setTotal(tStaffAttendancePageInfo.getTotal());
//        staffAttendancePageVoPageInfo.setStartRow(tStaffAttendancePageInfo.getStartRow());
//        staffAttendancePageVoPageInfo.setEndRow(tStaffAttendancePageInfo.getEndRow());
//        staffAttendancePageVoPageInfo.setNextPage(tStaffAttendancePageInfo.getNextPage());
//        staffAttendancePageVoPageInfo.setLastPage(tStaffAttendancePageInfo.getLastPage());
        return staffAttendancePageVoPageInfo;
    }*/


    //CMS后台库存分页列表
    @Override
    public PageInfo<CmsStaffAttendancePageVo> getAttendanceList(AttendancePageParam attendancePageParam) {

        if(attendancePageParam.getPageNo() == 0 ||attendancePageParam.getPageSize() == 0){
            attendancePageParam.setPageNo(1);
            attendancePageParam.setPageSize(10);
        }
        if(attendancePageParam.getPageSize() > 1000){
            attendancePageParam.setPageSize(1000);
        }

        ArrayList<CmsStaffAttendancePageVo> cmsStaffAttendancePageVoList = new ArrayList<>();
        //如果根据名字或者艺名搜索需要吊发型师接口获取发型师ID查询
        if(attendancePageParam.getStaffInfo() != null && attendancePageParam.getStaffInfo() !=""){
            List<Long> cmsCraftsmanList = otherService.getCmsCraftsmanList(attendancePageParam.getStaffInfo());
            if(cmsCraftsmanList !=null && cmsCraftsmanList.size() >0)
            {
                attendancePageParam.setStaffIds(cmsCraftsmanList);
            }else{
                List<Long> staffId = new ArrayList<>();
                staffId.add(-1L);
                attendancePageParam.setStaffIds(staffId);
            }
//            //如果是ID名字一起搜索需要取交集
//            if(attendancePageParam.getStaffInfo() != null && attendancePageParam.getStaffInfo() !="" && attendancePageParam.getStaffId()!=null)
//            {
//                ArrayList<Long> staffId = new ArrayList<>();
//                staffId.add(attendancePageParam.getStaffId());
//                List<Long> intersection = cmsCraftsmanList.stream().filter(item -> staffId.contains(item)).collect(Collectors.toList());
//                attendancePageParam.setStaffIds(intersection);
//            }
         }
        //如果时间为空默认取当天的数据
        if(attendancePageParam.getStartDate() == ""||  attendancePageParam.getStartDate() ==null&&attendancePageParam.getEndDate() == ""||attendancePageParam.getEndDate() ==null){
            attendancePageParam.setStartDate(TimeUtil.DateToFormat(new Date(), "yyyy-MM-dd"));
        }
        //分页
        Integer pageNo = attendancePageParam.getPageNo();
        Integer pageSize = attendancePageParam.getPageSize();
        PageHelper.startPage(pageNo, pageSize);
        List<TStaffAttendance> tStaffAttendances = staffAttendanceMapper.selectStaffAttendancePageList(attendancePageParam);
        PageInfo<TStaffAttendance> tStaffAttendancePageInfo = new PageInfo<>(tStaffAttendances);
        List<TStaffAttendance> list = tStaffAttendancePageInfo.getList();
        if(list != null && list.size()>0){
            //筛选重复发型师ID
            List<Long> staffIdList = list.stream().map(a -> {
                return new Long[]{a.getStaffId(), a.getModifier()};
            }).flatMap(Arrays::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());
//            //根据发型师ID获取发型师信息
            List<StaffInfoVo> staffInfoVoList = otherService.getStaffInfoVo(staffIdList);
            for (TStaffAttendance tStaffAttendance : list) {
                CmsStaffAttendancePageVo cmsStaffAttendancePageVo = new CmsStaffAttendancePageVo(tStaffAttendance);
                if(staffInfoVoList != null && staffInfoVoList.size()>0){
                    for(StaffInfoVo infoVo : staffInfoVoList){
                        if(infoVo.getJobseekerId().equals(tStaffAttendance.getStaffId())){
                            cmsStaffAttendancePageVo.setStaffId(infoVo.getCode());
                            cmsStaffAttendancePageVo.setStaffName(infoVo.getName() == null ? null :infoVo.getName());
                            cmsStaffAttendancePageVo.setStaffNickName(infoVo.getCraftsName() == null ? null :infoVo.getCraftsName());
                        }
                        if(infoVo.getJobseekerId().equals(tStaffAttendance.getModifier())){
                            cmsStaffAttendancePageVo.setModifierName(infoVo.getName() == null ? null :infoVo.getName());
                        }
                    }
                }
                cmsStaffAttendancePageVoList.add(cmsStaffAttendancePageVo);
            }

        }
        //数据拷贝返回前端需要的数据
        PageInfo<CmsStaffAttendancePageVo> staffAttendancePageVoPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(tStaffAttendancePageInfo, staffAttendancePageVoPageInfo);
        staffAttendancePageVoPageInfo.setList(cmsStaffAttendancePageVoList);
        return staffAttendancePageVoPageInfo;
    }

    /**
     * CMS获取排班详情
     * @param attendanceId
     * @return
     */
    @Override
    public CmsStaffAttendanceVo getAttendanceInfo(Integer attendanceId) {

        //排版信息
        TStaffAttendance tStaffAttendance = staffAttendanceMapper.selectByPrimaryKey(attendanceId);
        CmsStaffAttendanceVo cmsStaffAttendanceVo = new CmsStaffAttendanceVo(tStaffAttendance);

        //获取发型师信息
        List<Long> staffIds = new ArrayList<>();
        staffIds.add(tStaffAttendance.getStaffId());
        staffIds.add(tStaffAttendance.getCreator());
        Set setStaffId = new HashSet(staffIds);
        List staffIdList = new ArrayList(setStaffId);
        List<StaffInfoVo> staffInfoVo = otherService.getStaffInfoVo(staffIdList);

        //获取发型师信息
        if(staffInfoVo!=null &&staffInfoVo.size()>0){
            for (StaffInfoVo infoVo : staffInfoVo) {
                if(infoVo.getJobseekerId().equals(tStaffAttendance.getStaffId())){
                    cmsStaffAttendanceVo.setStaffNickName(infoVo.getCraftsName());
                }
                if(infoVo.getJobseekerId().equals(tStaffAttendance.getCreator())){
                    cmsStaffAttendanceVo.setCreatorName(infoVo.getName());
                }
            }
        }
        //当日库存
        List<CmsStaffStockVo> cmsStaffStockVos =  new ArrayList<>();
        List<TStaffStock> tStaffStocks = staffStockMapper.selectByAttendanceId(attendanceId);
        if(tStaffStocks!=null&&tStaffStocks.size()>0){
            for (TStaffStock tStaffStock : tStaffStocks) {
                CmsStaffStockVo cmsStaffStockVo = new CmsStaffStockVo();
                cmsStaffStockVo.setId(tStaffStock.getId());
                cmsStaffStockVo.setStartTime(TimeUtil.DateToFormat(tStaffStock.getStartTime(),"HH:mm"));
                cmsStaffStockVo.setLineNo(tStaffStock.getLineNo());
                cmsStaffStockVo.setStatus(tStaffStock.getStatus());
                cmsStaffStockVo.setStatusName(StockStatusEnum.getAttendanceType(tStaffStock.getStatus()).getDescription());
                cmsStaffStockVos.add(cmsStaffStockVo);
            }
        }
        cmsStaffAttendanceVo.setCmsStaffStockVoList(cmsStaffStockVos);
        List<TStaffClockIn> tStaffClockIns = staffClockInMapper.selectStaffClockInInfo(tStaffAttendance.getStaffId(), tStaffAttendance.getStoreId(), tStaffAttendance.getDate());
        //打卡记录
        ArrayList<CmsStaffClockInVo> cmsStaffClockInVoList = new ArrayList<>();
        for (TStaffClockIn tStaffClockIn : tStaffClockIns) {
            CmsStaffClockInVo cmsStaffClockInVo = new CmsStaffClockInVo(tStaffClockIn);
            cmsStaffClockInVoList.add(cmsStaffClockInVo);
        }

         cmsStaffAttendanceVo.setCmsStaffClockInVoList(cmsStaffClockInVoList);
        return cmsStaffAttendanceVo;
    }

    /**
     * @description  存在Babar双库存需要预处理
     * @Author 情绪极其不稳定的Shadow
     * @Param [sourceStockList <-> 原库存, targetStockList <-> 新库存]
     * @return java.util.List<com.xingkeduo.model.po.TStaffStock>
     **/
    private List<TStaffStock> babarStockPretreatment(List<TStaffStock> sourceStockList, List<TStaffStock> targetStockList, Byte type){
        TStaffStock maxOrMinTimeStock = new TStaffStock();
        //获取平移之后库存的最大开始时间
        //MORNING_SHIFT(1, "早班"), NIGHT_SHIFT(2, "晚班")
        if(type == 1){
            for(TStaffStock staffStock : targetStockList){
                if(StringUtils.isEmpty(maxOrMinTimeStock.getId())){
                    maxOrMinTimeStock = staffStock;
                    continue;
                }
                long nowTime = staffStock.getStartTime().getTime();
                long maxTime = maxOrMinTimeStock.getStartTime().getTime();
                if(nowTime > maxTime){
                    maxOrMinTimeStock = staffStock;
                }
            }
        }else if(type == 2){
            for(TStaffStock staffStock : targetStockList){
                if(StringUtils.isEmpty(maxOrMinTimeStock.getId())){
                    maxOrMinTimeStock = staffStock;
                    continue;
                }
                long nowTime = staffStock.getStartTime().getTime();
                long maxTime = maxOrMinTimeStock.getStartTime().getTime();
                if(nowTime < maxTime){
                    maxOrMinTimeStock = staffStock;
                }
            }
        } else {
            return sourceStockList;
        }

        log.info("平移后最大的库存开始时间--->>>"+maxOrMinTimeStock.getStartTime());

        for(int i = 0; i < sourceStockList.size(); i++){
            //找到maxTimeStock对应原库存中的库存节点
            TStaffStock staffStockOne = sourceStockList.get(i);
            if(maxOrMinTimeStock.getStartTime().compareTo(staffStockOne.getStartTime()) == 0){
                //判断原库存的对应时间节点是否存在订单
                if(!StringUtils.isEmpty(sourceStockList.get(i).getOrderId())){
                    if(i == sourceStockList.size()-1){
                        break;
                    }
                    TStaffStock staffStock = sourceStockList.get(i + 1);
                    // TODO 如果订单号一样 按照BaBar逻辑处理 目前的处理方式 待服务订单提示 其他状态 清空订单相关数据 重置库存状态为空闲
                    if(staffStock.getOrderId().equals(staffStockOne.getOrderId())){
                        if(staffStockOne.getStatus() == 2){
                            log.info("staffStockOne.getStatus()--->>>"+staffStockOne.getStatus());
                            log.info("staffStockOne.getOrderId()--->>>"+staffStockOne.getOrderId());
                            log.info("staffStockOne.setLineNo()--->>>"+staffStockOne.getLineNo());
                            log.info("staffStockOne.getUserPath()--->>>"+staffStockOne.getUserPath());
                            log.info("staffStockOne.getStartTime()--->>>"+staffStockOne.getStartTime());
                            staffStockOne.setOrderId(null);
                            staffStockOne.setLineNo(null);
                            staffStockOne.setUserPath(null);
                            staffStockOne.setStatus((byte)0);
                            break;
                        }else{
                            log.info("staffStock.getStatus()--->>>"+staffStock.getStatus());
                            log.info("staffStock.getOrderId()--->>>"+staffStock.getOrderId());
                            log.info("staffStock.setLineNo()--->>>"+staffStock.getLineNo());
                            log.info("staffStock.getUserPath()--->>>"+staffStock.getUserPath());
                            log.info("staffStock.getStartTime()--->>>"+staffStock.getStartTime());
                            staffStock.setOrderId(null);
                            staffStock.setLineNo(null);
                            staffStock.setUserPath(null);
                            staffStock.setStatus((byte)0);
                            break;
                        }
                    }
                }
            }
        }
        return sourceStockList;
    }
}
